Core.Test.registerTest({
	group: "mock",
	name: "Mocking with specified call count",
	
	 _should: 
	 {
		fail: 
		{
            "Call count should default to 1 and fail": 1,
            "Call count set to 1 should fail when method isn't called": 1,
            "Call count set to 1 should fail when method is called twice": 1,
            "Call count set to 0 should fail when method is called once": 1
        }
    },

    /*
     * Tests that leaving off callCount results in a callCount of 1, so
     * calling the stub method once should make the test pass.
     */
    "Call count should default to 1 and pass": function( )
    {
	var stub = { };
    T.Mock.expect( stub, { method: "method" } );
        
	stub.method( );                
	T.Mock.verify( stub );            
    },
    
    /*
     * Tests that leaving off callCount results in a callCount of 1, so
     * not calling the stub method once should make the test fail.
     */
    "Call count should default to 1 and fail": function( )
    {
		var stub = { };
		T.Mock.expect( stub, { method: "method" } );

		T.Mock.verify( stub );            
    },
    
    /*
     * Tests that setting callCount to 1 and
     * calling the stub method once should make the test pass.
     */
    "Call count set to 1 should pass when method is called once": function( )
	{
		var stub = { };
		T.Mock.expect( stub, { method: "method", calls: 1 } );
        
        stub.method( );                
        T.Mock.verify( stub );            
    },
    
    /*
     * Tests that setting callCount to 1 and not
     * calling the stub method once should make the test fail.
     */
    "Call count set to 1 should fail when method isn't called": function( )
    {
		var stub = { };
        
        T.Mock.expect( stub, { method: "method", calls: 1 });
        T.Mock.verify( stub );            
    },
                
    /*
     * Tests that setting callCount to 1 and not
     * calling the stub method twice should make the test fail.
     */
    "Call count set to 1 should fail when method is called twice": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", calls: 1 });
        
        stub.method( );
        stub.method( );
        
        T.Mock.verify( stub );            
    },
                
    /*
     * Tests that setting callCount to 0 and
     * calling the stub method once should make the test fail.
     */
    "Call count set to 0 should fail when method is called once": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", calls: 0 });
        
        stub.method( );                
        T.Mock.verify( stub );            
    },
    
    /*
     * Tests that setting callCount to 0 and not
     * calling the stub method once should make the test pass.
     */
    "Call count set to 0 should pass when method isn't called": function( )
    {
        var stub = { };
        
        T.Mock.expect( stub, { method: "method", calls: 0 });
        T.Mock.verify( stub );            
    }        
});

// ------------------------------------------
// T.Unit.MockBasics
// ------------------------------------------
Core.Test.registerTest({
	group: "mock",
	name: "Mocking basics",
	
	_should:
	{
        fail: 
        {
			"Passing an incorrect number of arguments should make the test fail": 1,
            "Passing an inexact argument should make the test fail" : 1,
            
            "Passing a number to an Boolean argument should make the test fail": 1,
            "Passing a string to an Boolean argument should make the test fail": 1,
            "Passing a object to an Boolean argument should make the test fail": 1,
            "Passing a function to an Boolean argument should make the test fail": 1,
            "Passing a null to an Boolean argument should make the test fail": 1,
            
            "Passing a number to an String argument should make the test fail": 1,
            "Passing a boolean to an String argument should make the test fail": 1,
            "Passing a object to an String argument should make the test fail": 1,
            "Passing a function to an String argument should make the test fail": 1,
            "Passing a null to an String argument should make the test fail": 1,
            
            "Passing a string to an Number argument should make the test fail": 1,
            "Passing a boolean to an Number argument should make the test fail": 1,
            "Passing a object to an Number argument should make the test fail": 1,
            "Passing a function to an Number argument should make the test fail": 1,
            "Passing a null to an Number argument should make the test fail": 1,
            
            "Passing a string to an Object argument should make the test fail": 1,
            "Passing a boolean to an Object argument should make the test fail": 1,
            "Passing a number to an Object argument should make the test fail": 1,
            "Passing a null to an Object argument should make the test fail": 1,
            
            "Passing a string to an Function argument should make the test fail": 1,
            "Passing a boolean to an Function argument should make the test fail": 1,
            "Passing a number to an Function argument should make the test fail": 1,
            "Passing a object to an Function argument should make the test fail": 1,
            "Passing a null to an Function argument should make the test fail": 1
        }
    },

    /*
     * Tests that when the number of arguments is verified, the test passes.
     */
    "Passing correct number of arguments should make the test pass": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Any ] });
        
        stub.method( 1 );                
        T.Mock.verify( stub );            
    },
    
    /*
     * Tests that when the number of arguments is not verified, the test fails.
     */
    "Passing an incorrect number of arguments should make the test fail": function( )
    {
       var stub = { };
       T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Any ] });
        
        stub.method( 1, 2 );                
        T.Mock.verify( stub );            
    },
    
    /*
     * Tests that passing the exactly specified argument causes the test to pass.
     */
    "Passing the exact argument should make the test pass": function( )
    {
        var arg = { };
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ arg ] });
        
        stub.method( arg );                
        T.Mock.verify( stub );            
    },
    
    /*
     * Tests that passing an argument that isn't exactly specified argument causes the test to fail.
     */
    "Passing an inexact argument should make the test fail": function( )
    {
        var arg = { };
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ arg ] });
        
        stub.method( { } );                
        T.Mock.verify( stub );            
    },

    //Mock.Value.Any tests --------------------------------------
    
    /*
     * Tests that passing a number to an argument specified as Mock.Value.Any
     * results cause the test to pass.
     */
    "Passing a number to an Any argument should make the test pass": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Any ] });
        
        stub.method( 1 );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a boolean to an argument specified as Mock.Value.Any
     * results cause the test to pass.
     */
    "Passing a boolean to an Any argument should make the test pass": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Any ] });
        
        stub.method( true );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a string to an argument specified as Mock.Value.Any
     * results cause the test to pass.
     */
    "Passing a string to an Any argument should make the test pass": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Any ] });
        
        stub.method( "" );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing an object to an argument specified as Mock.Value.Any
     * results cause the test to pass.
     */
    "Passing a object to an Any argument should make the test pass": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Any ] });
        
        stub.method( { } );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a function to an argument specified as Mock.Value.Any
     * results cause the test to pass.
     */
    "Passing a function to an Any argument should make the test pass": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Any ] });
        
        stub.method( function( ){ } );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a null to an argument specified as Mock.Value.Any
     * results cause the test to pass.
     */
    "Passing a null to an Any argument should make the test pass": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Any ] });
        
        stub.method( null );                
        T.Mock.verify( stub );            
    },

    //Mock.Value.Boolean tests --------------------------------------
    
    /*
     * Tests that passing a number to an argument specified as Mock.Value.Boolean
     * results cause the test to fail.
     */
    "Passing a number to an Boolean argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Boolean ] });
        
        stub.method( 1 );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a boolean to an argument specified as Mock.Value.Boolean
     * results cause the test to pass.
     */
    "Passing a boolean to an Boolean argument should make the test pass": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Boolean ] });
        
        stub.method( true );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a string to an argument specified as Mock.Value.Boolean
     * results cause the test to fail.
     */
    "Passing a string to an Boolean argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Boolean ] });
        
        stub.method( "" );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing an object to an argument specified as Mock.Value.Boolean
     * results cause the test to fail.
     */
    "Passing a object to an Boolean argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Boolean ] });
        
        stub.method( { } );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a function to an argument specified as Mock.Value.Boolean
     * results cause the test to fail.
     */
    "Passing a function to an Boolean argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Boolean ] });
        
        stub.method( function( ){ } );                
        T.Mock.verify( stub );            
    },            
    
    /*
     * Tests that passing a null to an argument specified as Mock.Value.Boolean
     * results cause the test to fail.
     */
    "Passing a null to an Boolean argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Boolean ] });
        
        stub.method( null );                
        T.Mock.verify( stub );            
    },
    
    //Mock.Value.String tests --------------------------------------
    
    /*
     * Tests that passing a number to an argument specified as Mock.Value.String
     * results cause the test to fail.
     */
    "Passing a number to an String argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.String ] });
        
        stub.method( 1 );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a boolean to an argument specified as Mock.Value.String
     * results cause the test to fail.
     */
    "Passing a boolean to an String argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.String ] });
        
        stub.method( true );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a string to an argument specified as Mock.Value.String
     * results cause the test to pass.
     */
    "Passing a string to an String argument should make the test pass": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method",  args: [ Mock.Value.String ] });
        
        stub.method( "" );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing an object to an argument specified as Mock.Value.String
     * results cause the test to fail.
     */
    "Passing a object to an String argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.String ] });
        
        stub.method( { } );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a function to an argument specified as Mock.Value.String
     * results cause the test to fail.
     */
    "Passing a function to an String argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.String ] });
        
        stub.method( function( ){ } );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a null to an argument specified as Mock.Value.String
     * results cause the test to fail.
     */
    "Passing a null to an String argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.String ] });
        
        stub.method( null );                
        T.Mock.verify( stub );            
    }, 

    //Mock.Value.Number tests --------------------------------------
    
    /*
     * Tests that passing a number to an argument specified as Mock.Value.Number
     * results cause the test to pass.
     */
    "Passing a number to an Number argument should make the test pass": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Number ] });
        
        stub.method( 1 );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a boolean to an argument specified as Mock.Value.Number
     * results cause the test to fail.
     */
    "Passing a boolean to an Number argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Number ] });
        
        stub.method( true );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a string to an argument specified as Mock.Value.Number
     * results cause the test to fail.
     */
    "Passing a string to an Number argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Number ] });
        
        stub.method( "" );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing an object to an argument specified as Mock.Value.Number
     * results cause the test to fail.
     */
    "Passing a object to an Number argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Number ] });
        
        stub.method( { } );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a function to an argument specified as Mock.Value.Number
     * results cause the test to fail.
     */
    "Passing a function to an Number argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Number ] });
        
        stub.method( function( ){ } );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a null to an argument specified as Mock.Value.Number
     * results cause the test to fail.
     */
    "Passing a null to an Number argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Number ] });
        
        stub.method( null );                
        T.Mock.verify( stub );            
    },          
          
    //Mock.Value.Function tests --------------------------------------
    
    /*
     * Tests that passing a number to an argument specified as Mock.Value.Function
     * results cause the test to fail.
     */
    "Passing a number to an Function argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Function ] });
        
        stub.method( 1 );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a boolean to an argument specified as Mock.Value.Function
     * results cause the test to fail.
     */
    "Passing a boolean to an Function argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Function ] });
        
        stub.method( true );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a string to an argument specified as Mock.Value.Function
     * results cause the test to fail.
     */
    "Passing a string to an Function argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Function ] });
        
        stub.method( "" );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing an object to an argument specified as Mock.Value.Function
     * results cause the test to fail.
     */
    "Passing a object to an Function argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Function ] });
        
        stub.method( { } );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a function to an argument specified as Mock.Value.Function
     * results cause the test to pass.
     */
    "Passing a function to an Function argument should make the test pass": function( )
   	{
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Function ] });
        
        stub.method( function( ){ } );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a null to an argument specified as Mock.Value.Function
     * results cause the test to fail.
     */
    "Passing a null to an Function argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Function ] });
        
        stub.method( null );                
        T.Mock.verify( stub );            
    },          

    //Mock.Value.Object tests --------------------------------------
    
    /*
     * Tests that passing a number to an argument specified as Mock.Value.Object
     * results cause the test to fail.
     */
    "Passing a number to an Object argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Object ] });
        
        stub.method( 1 );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a boolean to an argument specified as Mock.Value.Object
     * results cause the test to fail.
     */
    "Passing a boolean to an Object argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Object ] });
        
        stub.method( true );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a string to an argument specified as Mock.Value.Object
     * results cause the test to fail.
     */
    "Passing a string to an Object argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Object ] });
        
        stub.method( "" );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing an object to an argument specified as Mock.Value.Object
     * results cause the test to pass.
     */
    "Passing a object to an Object argument should make the test pass": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Object ] });
        
        stub.method( { } );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a function to an argument specified as Mock.Value.Object
     * results cause the test to pass.
     */
    "Passing a function to an Object argument should make the test pass": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Object ] });
        
        stub.method( function( ){ } );                
        T.Mock.verify( stub );            
    },

    /*
     * Tests that passing a null to an argument specified as Mock.Value.Object
     * results cause the test to fail.
     */
    "Passing a null to an Object argument should make the test fail": function( )
    {
        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.Object ] });
        
        stub.method( null );                
        T.Mock.verify( stub );            
    }
});


//------------------------------------------
//T.Unit.MockAsynchronous
//------------------------------------------

Core.Test.registerTest({
	group: "mock",
    name : "Asynchronous Tests",
    
    _should: {
    
        fail: { "A mock method called asynchronously shouldn't cause an error": 1 }
    },
    
    /*
     * Tests that when a mock method is called asynchronously, either via
     * timeout or XHR callback, that its error is properly handled and
     * the failure is logged to the test.
     */
    "A mock method called asynchronously shouldn't cause an error": function(){

        var stub = { };
        T.Mock.expect( stub, { method: "method", args: [ Mock.Value.String ] });
        
        setTimeout(function( ) { stub.method( null ); }, 250 );
        this.wait( function( ) { T.Mock.verify( stub ); }, 500 );
    }
});